using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Security;
using System.Text;
using UnityEngine;

public static class Utils
{
	private const char LIST_SPRITER = ',';

	private const char KEY_VALUE_SPRITER = ':';

	private const char MAP_SPRITER = ',';

	public const string COLOR_TAG = "color";

	public static string LoadResource(string fileName)
	{
		UnityEngine.Object @object = Resources.Load(fileName);
		if (@object != null)
		{
			string result = @object.ToString();
			Resources.UnloadAsset(@object);
			return result;
		}
		return string.Empty;
	}

	public static string LoadFile(string fileName)
	{
		if (File.Exists(fileName))
		{
			using (StreamReader streamReader = File.OpenText(fileName))
			{
				return streamReader.ReadToEnd();
			}
		}
		return string.Empty;
	}

	public static byte[] LoadByteFile(string fileName)
	{
		if (File.Exists(fileName))
		{
			return File.ReadAllBytes(fileName);
		}
		return null;
	}

	public static List<T> LoadXML<T>(string fileName)
	{
		string text = LoadXMLContent(fileName);
		return LoadXMLText<T>(text);
	}

	public static string LoadXMLContent(string fileName)
	{
		return LoadResource(fileName);
	}

	public static List<T> LoadXMLText<T>(string text)
	{
		List<T> list = new List<T>();
		try
		{
			if (!string.IsNullOrEmpty(text))
			{
				Type typeFromHandle = typeof(T);
				SecurityElement xml = XMLParser.LoadXML(text);
				Dictionary<int, Dictionary<string, string>> dictionary = XMLParser.LoadIntMap(xml, text);
				PropertyInfo[] properties = typeFromHandle.GetProperties(~BindingFlags.Static);
				{
					foreach (KeyValuePair<int, Dictionary<string, string>> item in dictionary)
					{
						ConstructorInfo constructorInfo = typeFromHandle.GetConstructor(BindingFlags.Public | BindingFlags.Instance, null, Type.EmptyTypes, null);
						object obj = constructorInfo.Invoke(null);
						PropertyInfo[] array = properties;
						foreach (PropertyInfo propertyInfo in array)
						{
							if (propertyInfo.Name == "id")
							{
								propertyInfo.SetValue(obj, item.Key, null);
							}
							else
							{
								try
								{
									if (item.Value.ContainsKey(propertyInfo.Name))
									{
										object value = GetValue(item.Value[propertyInfo.Name], propertyInfo.PropertyType);
										propertyInfo.SetValue(obj, value, null);
									}
								}
								catch (Exception ex)
								{
									LoggerHelper.Debug("LoadXML error: " + item.Value[propertyInfo.Name] + " " + propertyInfo.PropertyType);
									LoggerHelper.Except(ex);
								}
							}
						}
						list.Add((T)obj);
					}
					return list;
				}
			}
			return list;
		}
		catch (Exception ex2)
		{
			LoggerHelper.Except(ex2);
			LoggerHelper.Error("error text: \n" + text);
			return list;
		}
	}

	public static string GetFileNameWithoutExtention(string fileName, char separator = '/')
	{
		string fileName2 = GetFileName(fileName, separator);
		return GetFilePathWithoutExtention(fileName2);
	}

	public static string GetFilePathWithoutExtention(string fileName)
	{
		return fileName.Substring(0, fileName.LastIndexOf('.'));
	}

	public static string GetDirectoryName(string fileName)
	{
		return fileName.Substring(0, fileName.LastIndexOf('/'));
	}

	public static string GetFileName(string path, char separator = '/')
	{
		return path.Substring(path.LastIndexOf(separator) + 1);
	}

	public static string PathNormalize(this string str)
	{
		return str.Replace("\\", "/").ToLower();
	}

	public static string ReplaceFirst(this string input, string oldValue, string newValue, int startAt = 0)
	{
		int num = input.IndexOf(oldValue, startAt);
		if (num < 0)
		{
			return input;
		}
		return input.Substring(0, num) + newValue + input.Substring(num + oldValue.Length);
	}

	public static object GetValue(string value, Type type)
	{
		if (type == null)
		{
			return null;
		}
		if (type == typeof(string))
		{
			return value;
		}
		if (type == typeof(int))
		{
			return Convert.ToInt32(Convert.ToDouble(value));
		}
		if (type == typeof(float))
		{
			return float.Parse(value);
		}
		if (type == typeof(byte))
		{
			return Convert.ToByte(Convert.ToDouble(value));
		}
		if (type == typeof(sbyte))
		{
			return Convert.ToSByte(Convert.ToDouble(value));
		}
		if (type == typeof(uint))
		{
			return Convert.ToUInt32(Convert.ToDouble(value));
		}
		if (type == typeof(short))
		{
			return Convert.ToInt16(Convert.ToDouble(value));
		}
		if (type == typeof(long))
		{
			return Convert.ToInt64(Convert.ToDouble(value));
		}
		if (type == typeof(ushort))
		{
			return Convert.ToUInt16(Convert.ToDouble(value));
		}
		if (type == typeof(ulong))
		{
			return Convert.ToUInt64(Convert.ToDouble(value));
		}
		if (type == typeof(double))
		{
			return double.Parse(value);
		}
		if (type == typeof(bool))
		{
			if (value == "0")
			{
				return false;
			}
			if (value == "1")
			{
				return true;
			}
			return bool.Parse(value);
		}
		if (type.BaseType == typeof(Enum))
		{
			return GetValue(value, Enum.GetUnderlyingType(type));
		}
		if (type == typeof(Vector3))
		{
			ParseVector3(value, out Vector3 result);
			return result;
		}
		if (type == typeof(Quaternion))
		{
			ParseQuaternion(value, out Quaternion result2);
			return result2;
		}
		if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Dictionary<,>))
		{
			Type[] genericArguments = type.GetGenericArguments();
			Dictionary<string, string> dictionary = value.ParseMap();
			object obj = type.GetConstructor(Type.EmptyTypes).Invoke(null);
			{
				foreach (KeyValuePair<string, string> item in dictionary)
				{
					object value2 = GetValue(item.Key, genericArguments[0]);
					object value3 = GetValue(item.Value, genericArguments[1]);
					type.GetMethod("Add").Invoke(obj, new object[2]
					{
						value2,
						value3
					});
				}
				return obj;
			}
		}
		if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(List<>))
		{
			Type type2 = type.GetGenericArguments()[0];
			List<string> list = value.ParseList();
			object obj2 = type.GetConstructor(Type.EmptyTypes).Invoke(null);
			{
				foreach (string item2 in list)
				{
					object value4 = GetValue(item2, type2);
					type.GetMethod("Add").Invoke(obj2, new object[1]
					{
						value4
					});
				}
				return obj2;
			}
		}
		return null;
	}

	public static bool ParseVector3(string _inputString, out Vector3 result)
	{
		string text = _inputString.Trim();
		result = default(Vector3);
		if (text.Length < 7)
		{
			return false;
		}
		try
		{
			string[] array = text.Split(',');
			if (array.Length != 3)
			{
				return false;
			}
			result.x = float.Parse(array[0]);
			result.y = float.Parse(array[1]);
			result.z = float.Parse(array[2]);
			return true;
		}
		catch (Exception ex)
		{
			LoggerHelper.Error("Parse Vector3 error: " + text + ex.ToString());
			return false;
		}
	}

	public static bool ParseQuaternion(string _inputString, out Quaternion result)
	{
		string text = _inputString.Trim();
		result = default(Quaternion);
		if (text.Length < 9)
		{
			return false;
		}
		try
		{
			string[] array = text.Split(',');
			if (array.Length != 4)
			{
				return false;
			}
			result.x = float.Parse(array[0]);
			result.y = float.Parse(array[1]);
			result.z = float.Parse(array[2]);
			result.w = float.Parse(array[3]);
			return true;
		}
		catch (Exception ex)
		{
			LoggerHelper.Error("Parse Quaternion error: " + text + ex.ToString());
			return false;
		}
	}

	public static Dictionary<string, string> ParseMap(this string strMap, char keyValueSpriter = ':', char mapSpriter = ',')
	{
		Dictionary<string, string> dictionary = new Dictionary<string, string>();
		if (string.IsNullOrEmpty(strMap))
		{
			return dictionary;
		}
		string[] array = strMap.Split(mapSpriter);
		for (int i = 0; i < array.Length; i++)
		{
			if (string.IsNullOrEmpty(array[i]))
			{
				continue;
			}
			string[] array2 = array[i].Split(keyValueSpriter);
			if (array2.Length == 2)
			{
				if (!dictionary.ContainsKey(array2[0]))
				{
					dictionary.Add(array2[0], array2[1]);
				}
				else
				{
					LoggerHelper.Warning($"Key {array2[0]} already exist, index {i} of {strMap}.");
				}
			}
			else
			{
				LoggerHelper.Warning($"KeyValuePair are not match: {array[i]}, index {i} of {strMap}.");
			}
		}
		return dictionary;
	}

	public static List<string> ParseList(this string strList, char listSpriter = ',')
	{
		List<string> list = new List<string>();
		if (string.IsNullOrEmpty(strList))
		{
			return list;
		}
		string text = strList.Trim();
		if (string.IsNullOrEmpty(strList))
		{
			return list;
		}
		string[] array = text.Split(listSpriter);
		string[] array2 = array;
		foreach (string text2 in array2)
		{
			if (!string.IsNullOrEmpty(text2))
			{
				list.Add(text2.Trim());
			}
		}
		return list;
	}

	[DllImport("key", CallingConvention = CallingConvention.Cdecl)]
	public static extern int GetIndexKey(int i);

	[DllImport("key", CallingConvention = CallingConvention.Cdecl)]
	public static extern int GetResKey(int i);

	public static byte[] GetIndexNumber()
	{
		return new byte[8]
		{
			123,
			52,
			53,
			9,
			12,
			6,
			23,
			26
		};
	}

	public static byte[] GetResNumber()
	{
		return new byte[8]
		{
			231,
			20,
			185,
			13,
			20,
			127,
			81,
			79
		};
	}

	public static string FormatMD5(byte[] data)
	{
		return BitConverter.ToString(data).Replace("-", string.Empty).ToLower();
	}

	public static string PackMap<T, U>(this IEnumerable<KeyValuePair<T, U>> map, char keyValueSpriter = ':', char mapSpriter = ',')
	{
		if (map.Count() == 0)
		{
			return string.Empty;
		}
		StringBuilder stringBuilder = new StringBuilder();
		foreach (KeyValuePair<T, U> item in map)
		{
			stringBuilder.AppendFormat("{0}{1}{2}{3}", item.Key, keyValueSpriter, item.Value, mapSpriter);
		}
		return stringBuilder.ToString().Remove(stringBuilder.Length - 1, 1);
	}

	public static string PackList<T>(this List<T> list, char listSpriter = ',')
	{
		if (list.Count == 0)
		{
			return string.Empty;
		}
		StringBuilder stringBuilder = new StringBuilder();
		foreach (T item in list)
		{
			stringBuilder.AppendFormat("{0}{1}", item, listSpriter);
		}
		stringBuilder.Remove(stringBuilder.Length - 1, 1);
		return stringBuilder.ToString();
	}

	private static bool ParseColor(string text, ref int index)
	{
		int length = text.Length;
		if (index + 1 >= length)
		{
			return false;
		}
		if (text[index] != '[')
		{
			return false;
		}
		char c = text[index + 1];
		if (c == '/')
		{
			int num = index + 2;
			int num2 = num + "color".Length + 1;
			if (text.Length < num2)
			{
				return false;
			}
			string text2 = text.Substring(num, "color".Length);
			if (!text2.Equals("color"))
			{
				return false;
			}
			if (text[num2 - 1] != ']')
			{
				return false;
			}
			index = num2;
			return true;
		}
		int num3 = index + 1 + "color".Length;
		if (text.Length < num3 + 8)
		{
			return false;
		}
		string text3 = text.Substring(index + 1, "color".Length);
		if (!text3.Equals("color"))
		{
			return false;
		}
		if (text[num3] != ' ')
		{
			return false;
		}
		if (text[num3 + 1] != '#')
		{
			return false;
		}
		string s = text.Substring(num3 + 2, 6);
		uint result = 0u;
		if (!uint.TryParse(s, NumberStyles.HexNumber, null, out result))
		{
			return false;
		}
		index = num3 + 9;
		return true;
	}

	public static string WrapText(string text, int lineLength)
	{
		if (string.IsNullOrEmpty(text) || text.Length < lineLength || lineLength <= 0)
		{
			return text;
		}
		StringBuilder stringBuilder = new StringBuilder();
		int num = 0;
		float num2 = 0f;
		int length = text.Length;
		while (num < length)
		{
			char c = text[num];
			int index = num;
			if (ParseColor(text, ref index))
			{
				stringBuilder.Append(text.Substring(num, index - num));
				num = index;
				continue;
			}
			if (num2 >= (float)lineLength)
			{
				stringBuilder.Append('\n');
				num2 = 0f;
			}
			stringBuilder.Append(c);
			num2 = ((!char.IsNumber(c)) ? (num2 + 1f) : (num2 + 0.5f));
			num++;
		}
		return stringBuilder.ToString();
	}

	public static Vector2 DirToVector2(int dir)
	{
		Vector2 zero = Vector2.zero;
		switch (dir)
		{
			case 0:
				zero[1] = 1f;
				break;
			case 1:
				zero[1] = 1f;
				zero[0] = 1f;
				break;
			case 2:
				zero[0] = 1f;
				break;
			case 3:
				zero[1] = -1f;
				zero[0] = 1f;
				break;
			case 4:
				zero[1] = -1f;
				break;
			case 5:
				zero[1] = -1f;
				zero[0] = -1f;
				break;
			case 6:
				zero[0] = -1f;
				break;
			case 7:
				zero[1] = 1f;
				zero[0] = -1f;
				break;
		}
		return zero;
	}

	public static T ToEnum<T>(this string value, T defaultValue, bool ignoreCase = true)
	{
		try
		{
			return (T)Enum.Parse(typeof(T), value, ignoreCase);
		}
		catch (Exception)
		{
			return defaultValue;
		}
	}
}
